#include "keybutton.h"

static QueueHandle_t gpio_evt_queue = NULL;  // 定义队列句柄

/* GPIO Interrupt service Routine */
void IRAM_ATTR gpio_isr_handler(void* arg) 
{
    uint32_t gpio_num = (uint32_t) arg;  // 获取入口参数
    // xQueueSendFromISR的第二个参数需要传递数据的地址
    // 因为队列内部会复制这个地址指向的数据(gpio_num)到队列存储区
    xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL); // 把入口参数值发送到队列
}

/* GPIO Task function */
void gpio_task(void* arg)
{
    uint32_t io_num; // 定义变量 表示哪个GPIO
    for(;;) 
    {
        // xQueueReceive函数从队列接收数据:
        // 参数1 gpio_evt_queue: 队列句柄,指定从哪个队列接收
        // 参数2 &io_num: 接收缓冲区地址,数据将被复制到这里
        // 参数3 portMAX_DELAY: 最大等待时间,一直阻塞直到接收到数据
        // 返回值pdTRUE表示成功接收到数据
        if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) 
        {
            printf("GPIO[%"PRIu32"]intr, val: %d\n", io_num, gpio_get_level(io_num)); // 打印相关内容
        }
    }
}

void keybutton(void) 
{
    gpio_config_t io0_conf = {
        .intr_type = GPIO_INTR_NEGEDGE, // 下降沿中断
        .mode = GPIO_MODE_INPUT, // 输入模式
        .pin_bit_mask = 1<<GPIO_NUM_0, // 选择GPIO0
        .pull_down_en = 0, // 禁能内部下拉
        .pull_up_en = 1 // 使能内部上拉
    };

    gpio_config(&io0_conf);
    // 创建一个队列初始GPIO事件
    gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
    // 开启GPIO任务
    xTaskCreate(gpio_task, "gpio_task", 2048, NULL, 10, NULL);
    // 创建GPIO中断服务
    gpio_install_isr_service(0);
    // 给GPIO0添加中断处理
    gpio_isr_handler_add(GPIO_NUM_0, gpio_isr_handler, (void*) GPIO_NUM_0);
}


